package com.scs.application.modules.sys.controller;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.core.exception.BusinessException;
import com.scs.application.core.mvc.controller.CrudController;
import com.scs.application.core.query.QueryContext;
import com.scs.application.core.query.QueryContextHolder;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.modules.sys.entity.Menu;
import com.scs.application.modules.sys.model.PageResult;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.sys.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

@RestController
public class MenuController  extends CrudController<MenuService,Menu> {
    @Autowired
    MenuService menuService;
    @RequestMapping(value = "/program/menu/getList", method = RequestMethod.GET)
    public RestResult getMenuList() {
        String menuString = menuService.getDesignMenu();
        HashMap<String, Object> result = new HashMap<>();
        result.put("menu", menuString);
        return RestResult.ok("获取菜单成功！", result);
    }
    /*@RequestMapping(value = "/program/menu/save", method = RequestMethod.POST)
    public RestResult saveMenu(@RequestBody StringReceive entity) {
        String menuString = entity.getContents();
        menuService.saveMenu(menuString,entity.getDeleteIdList());
        return RestResult.ok("保存菜单成功！");
    }*/

    /**
     * 添加/更新数据
     */
    @Override
    @PostMapping("/program/menu/save")
    public RestResult saveItem(@Valid @RequestBody Menu entity) {
        boolean isOk = service.saveOrUpdate(entity);
        if (!isOk) {
            return RestResult.error("菜单保存失败");
        }
        return RestResult.ok("菜单保存成功", entity);
    }

    /**
     * 删除数据
     */
    @DeleteMapping("/program/menu/delete")
    public RestResult deleteItems(@RequestBody Map<String, Object> para) {
        List<Serializable> ids = (List<Serializable>) para.get("ids");
        BusinessException.throwErrorIf(ObjectUtil.length(ids) == 0, "删除失败，缺少参数");
        Boolean isOk = service.removeCascadeByIds(ids);
        if (!isOk) {
            return RestResult.error("菜单删除失败<br>可能所操作数据已被删除，请刷新页面重新尝试操作");
        }
        return RestResult.ok("菜单删除成功");
    }
    /**
     * 获取全部数据
     */
    @RequestMapping("/menu/all")
    public RestResult findAll(){
        List<Menu> models = menuService.list();
        return RestResult.ok("get menu all success", models);
    }
    /**
     * 获取菜单
     */
    @RequestMapping("/menu/getAppMenu")
    public RestResult getAppMenu(){
        List<Menu> userMenu = menuService.getUserMenu();
        List<Menu> models = userMenu.stream().filter(o -> "APP".equalsIgnoreCase(o.getMenuType())).collect(Collectors.toList());
        return RestResult.ok("get app menu success", models);
    }

    /**
     * 获取用户菜单
     * @return
     */
    @RequestMapping(value = "/program/menu/getUserMenu", method = RequestMethod.GET)
    public RestResult getUserMenu() {
        /*String menuString = JSON.toJSONString(menuService.getUserMenu());
        HashMap<String, Object> result = new HashMap<>();
        result.put("menu", menuString);*/

        List<Menu> userMenu = menuService.getUserMenu();

        return RestResult.ok("获取菜单成功！", userMenu);
    }

    /**
     * 获取用户菜单
     */
    @GetMapping("/menu/listByUser")
    public RestResult listByUser(@RequestParam String userId){
        List<Menu> models = menuService.listByUser(userId);
        return RestResult.ok("get menu success", models);
    }

    /**
     * 获取角色菜单
     * @param roleId
     * @return
     */
    @GetMapping("/menu/listByRole")
    public RestResult listByRole(@RequestParam String roleId){
        List<Menu> menus = menuService.listByRole(roleId);
        return RestResult.ok("查询成功", menus);
    }

    /**
    * @Description：获取菜单数据 角色编辑时，使用
     * @param roleId   角色id
     * @param getType  1:获取该角色未添加的菜单，2：获取该角色已添加的菜单
    */
    @RequestMapping("/menu/allForRoleEdit")
    public RestResult allForRoleEdit(String roleId,String getType){
        List<Menu> menuList = null;
        QueryWrapper queryWrapper = Wrappers.<Menu>query().orderByAsc("sort");
        if ("1".equals(getType)) {
            queryWrapper.ne("is_admin_menu","1");
            queryWrapper.ne("is_hidden","1");
            queryWrapper.notInSql("id","SELECT resource_id FROM sys_authority where target_id = '"+roleId+"'");
        } else if ("2".equals(getType)) {
            queryWrapper.inSql("id","SELECT resource_id FROM sys_authority where target_id = '"+roleId+"'");
        }
        menuList=menuService.list(queryWrapper);


        //已添加菜单，添加父节点
        if ( menuList!=null && menuList.size() > 0) {
            queryWrapper = Wrappers.<Menu>query().orderByAsc("sort");
            List<Menu> menuAllList = menuService.list(queryWrapper);
            menuList=this.getMenuParent(menuList,menuAllList);
        }

        //分级排序
         if ( menuList!=null && menuList.size() > 0) {
             List<Menu> menuLeval1List = menuList.stream().filter(menu -> StringUtils.isBlank(menu.getParentId()) || "0".equals(menu.getParentId())).collect(Collectors.toList());
             List<Menu> menuLevalOtherList = menuList.stream().filter(menu -> StringUtils.isNotBlank(menu.getParentId()) && !"0".equals(menu.getParentId())).collect(Collectors.toList());
             menuLeval1List= menuLeval1List.stream().sorted(Comparator.comparing(Menu::getSort)).collect(Collectors.toList());
             menuLevalOtherList= menuLevalOtherList.stream().sorted(Comparator.comparing(Menu::getSort)).collect(Collectors.toList());
             menuList=new ArrayList<Menu>();
             menuList.addAll(menuLeval1List);
             menuList.addAll(menuLevalOtherList);
        }

        return RestResult.ok("操作成功", menuList);
    }

    private List<Menu> getMenuParent(List<Menu> menuList,List<Menu> menuAllList){
        List<Menu> menuAddList = new ArrayList<Menu>();
        List<Menu> finalMenuList = menuList;
        menuList.stream().forEach(menu -> {
            if (StringUtils.isNotBlank(menu.getParentId()) && !"0".equals(menu.getParentId())) {
                List<Menu> menuParentList = finalMenuList.stream().filter(menu2 -> menu2.getId().equals(menu.getParentId())).collect(Collectors.toList());
                if (menuParentList ==null || menuParentList.size() < 1){
                    List<Menu> menuParent2List = menuAllList.stream().filter(
                            menu2 -> menu2.getId().equals(menu.getParentId())

                    ).collect(Collectors.toList());
                    if (menuParent2List !=null && menuParent2List.size() > 1){
                        throw  new BusinessException("菜单异常，主键重复，id=%s",menu.getParentId());
                    }
                    if (menuParent2List ==null || menuParent2List.size() < 1){
                        throw  new BusinessException("菜单异常，未找到父级菜单，parentid=%s",menu.getParentId());
                    }

                    //排除掉已隐藏的或者管理员菜单，app可以显示
                    if(
                        (
                            !"app".equalsIgnoreCase(menuParent2List.get(0).getMenuType())
                            &&
                            (menuParent2List.get(0).getIsAdminMenu() ==null || !menuParent2List.get(0).getIsAdminMenu())
                            && (menuParent2List.get(0).getIsHidden() == null || !menuParent2List.get(0).getIsHidden())
                        )
                        ||(
                                "app".equalsIgnoreCase(menuParent2List.get(0).getMenuType())
                                        && (menuParent2List.get(0).getIsHidden() == null || !menuParent2List.get(0).getIsHidden())
                        )
                    )
                    {
                        menuAddList.add(menuParent2List.get(0));
                    }
                }
            }
        });
        if (menuAddList.size() > 0){
            menuList.addAll(menuAddList);
            menuList=this.getMenuParent(menuList,menuAllList);
            return menuList;
        }
        return menuList;
    }

    /**业务选择时候使用
     *
     */
    @GetMapping("/menu/page")
    public PageResult pageForSelect() {
        QueryContext queryContext = QueryContextHolder.currentContext();
        queryContext.getWrapper().ne("'is_admin_menu'",1);
        queryContext.getWrapper().ne("'menu_type'","app");

        queryContext.getWrapper().notLike("url","demo");
        queryContext.getWrapper().notLike("url","frame");
        queryContext.getWrapper().notLike("url","cfg");
        queryContext.getWrapper().notLike("url","sys");
//        queryContext.getWrapper().notLike("url","report");
        queryContext.getWrapper().notLike("url","purchasewyt");
        queryContext.getWrapper().notLike("url","liweiguo");
        queryContext.getWrapper().notLike("url","help");
        queryContext.getWrapper().notLike("route","online");
        queryContext.getWrapper().notLike("title","废弃");
        queryContext.getWrapper().notLike("title","fsd");
        queryContext.getWrapper().notLike("ifnull(code,'')","app");
        queryContext.getWrapper().notLike("ifnull(code,'')","personal");

        queryContext.getWrapper().isNotNull("route");
        queryContext.getWrapper().isNotNull("url");


        IPage pageResult = service.page(queryContext);
        return PageResult.ok("查询成功", pageResult.getRecords(), pageResult.getTotal());
    }
}
